from pyjvm.instructions.common import Index8Instruction, Instruction
from pyjvm.runtime.thread import Frame


def store_val(frame: Frame, index: int):
    val = frame.operand_stack.pop()
    frame.local_vars[index] = val


class STORE(Index8Instruction):

    def execute(self, frame: Frame):
        store_val(frame, self.index)


class XASTORE(Instruction):

    def execute(self, frame: Frame):
        stack = frame.operand_stack
        obj = stack.pop()
        index = stack.pop()
        arr = stack.pop()
        arr.data[index] = obj


def get_store_val_index_func(index):
    def execute(self, frame: Frame):
        store_val(frame, index)

    return execute


def store_val_type(name: str, index: int):
    def execute(self, frame: Frame):
        store_val(frame, index)

    return type(name, (Instruction,), dict(execute=execute))


class ISTORE(STORE):
    pass


ISTORE_0 = store_val_type('ISTORE_0', 0)
ISTORE_1 = store_val_type('ISTORE_1', 1)
ISTORE_2 = store_val_type('ISTORE_2', 2)
ISTORE_3 = store_val_type('ISTORE_3', 3)


class LSTORE(STORE):
    pass


LSTORE_0 = store_val_type('LSTORE_0', 0)
LSTORE_1 = store_val_type('LSTORE_1', 1)
LSTORE_2 = store_val_type('LSTORE_2', 2)
LSTORE_3 = store_val_type('LSTORE_3', 3)


class FSTORE(STORE):
    pass


FSTORE_0 = store_val_type('FSTORE_0', 0)
FSTORE_1 = store_val_type('FSTORE_1', 1)
FSTORE_2 = store_val_type('FSTORE_2', 2)
FSTORE_3 = store_val_type('FSTORE_3', 3)


class DSTORE(STORE):
    pass


DSTORE_0 = store_val_type('DSTORE_0', 0)
DSTORE_1 = store_val_type('DSTORE_1', 1)
DSTORE_2 = store_val_type('DSTORE_2', 2)
DSTORE_3 = store_val_type('DSTORE_3', 3)


class ASTORE(STORE):
    pass


ASTORE_0 = store_val_type('ASTORE_0', 0)
ASTORE_1 = store_val_type('ASTORE_1', 1)
ASTORE_2 = store_val_type('ASTORE_2', 2)
ASTORE_3 = store_val_type('ASTORE_3', 3)


class IASTORE(XASTORE):
    pass


class LASTORE(XASTORE):
    pass


class FASTORE(XASTORE):
    pass


class DASTORE(XASTORE):
    pass


class AASTORE(XASTORE):
    pass


class BASTORE(XASTORE):
    pass


class CASTORE(XASTORE):
    pass


class SASTORE(XASTORE):
    pass


__all__ = ['ISTORE', 'ISTORE_0', 'ISTORE_1', 'ISTORE_2', 'ISTORE_3', 'IASTORE',
           'LASTORE', 'LSTORE_0', 'LSTORE_1', 'LSTORE_2', 'LSTORE_3', 'LSTORE',
           'FSTORE', 'FASTORE', 'FSTORE_0', 'FSTORE_2', 'FSTORE_1', 'FSTORE_3',
           'DSTORE', 'DSTORE_0', 'DASTORE', 'DSTORE_1', 'DSTORE_2', 'DSTORE_3',
           'BASTORE', 'CASTORE', 'SASTORE',
           'AASTORE', 'ASTORE', 'ASTORE_0', 'ASTORE_1', 'ASTORE_2', 'ASTORE_3']
